/* RMORPG - Dice.cpp
   Copyright (C) 2006, Michael Borgmann <mail@lechuck.de>
   This code is released under the new BSD license
 */

#include <ctime>
#include <cstdlib>
#include "Rolemaster/Dice.h"

using namespace rmorpg;

// Make Percentile Roll
int Dice::Roll1d100() {
	// return 1d100 roll
	return rand() % 100 + 1;
}

// Make a Low Open-ended Roll
int Dice::RollLowOpenEnded() {
	// check for unfortunate occurence
	if (roll <= 5) {
		// substract new roll and roll again if new roll >= 96
		int new_roll = 96;
		while (new_roll >= 96) {
			new_roll = Roll1d100();
			roll -= new_roll;
		}
	}

	// return low open-ended roll
	return roll;
}

// Make a High Open-ended Roll
int Dice::RollHighOpenEnded() {
	// check for fortunate occurence
	if (roll >= 96) {
		// add new roll and roll again if new roll >= 96
		int new_roll = 96;
		while (new_roll >= 96) {
			new_roll = Roll1d100();
			roll += new_roll;
		}
	}
	
	// return high open-ended roll
	return roll;
}

// Make an Open-ended Roll
int Dice::RollOpenEnded() {
	// check for un/fortunate occurence
	RollLowOpenEnded();
	RollHighOpenEnded();

	return roll;	
}

// Make a 1d10 Roll
int Dice::Roll1d10() {
	// return 1d10 roll
	return rand() % 10 + 1;
}

// Make a 1d5 Roll
int Dice::Roll1d5() {
	// return 1d5 roll
	return rand() % 5 + 1;
}

// Make a 1d8 Roll
int Dice::Roll1d8() {
	// return 1d8 roll
	return rand() % 8 + 1;
}

// Make a 5d10 roll
int Dice::Roll5d10() {
	// reset roll
	roll = 0;

	// sum 5 1d10 rolls
	for (int i = 0; i < 5; i++) {
		roll += Roll1d10();
	}

	// return 5d10 roll
	return roll;
}

// Make a 2d5 roll
int Dice::Roll2d5() {
	return Roll1d5() + Roll1d5();
}

// Default Constructor
Dice::Dice() {
	// initialize pseudo random generator by time
	srand(time(0));
}

// Default Destructor
Dice::~Dice() {}

// Simulate dice rolling
int Dice::Roll(int roll) {
	switch (roll) {
	case _1d100:
		return Roll1d100();
	case low_open_ended:
		this->roll = Roll1d100();
		return  RollLowOpenEnded();
	case high_open_ended:
		this->roll = Roll1d100();
		return RollHighOpenEnded();
	case open_ended:
		this->roll = Roll1d100();
		return RollOpenEnded();
	case _1d10:
		return Roll1d10();
	case _1d5:
		return Roll1d5();
	case _1d8:
		return Roll1d8();
	case _5d10:
		return Roll5d10();
	case _2d5:
		return Roll2d5();
	default:
		return false;
		break;
	}
}
